#include <p18f46k22.h>
#include <i2c.h>
#include "Accelerometre_parabole.h"

#define DEVICE_ADRESS_ACCELERO_WRITE 0x38
#define DEVICE_ADRESS_ACCELERO_READ 0x39

#define WHO_AM_I 0x0D			//Device ID register address --> register value 0x1A
#define XYZ_DATA_CFG 0x0E

#define CTRL_REG1 0x2A
#define CTRL_REG4 0x2D
#define CTRL_REG3 0x2C
#define CTRL_REG5 0x2E

#define INT_SOURCE 0x0C

#define OUT_X_MSB 0x01
#define OUT_X_LSB 0x02

#define OUT_Y_MSB 0x03
#define OUT_Y_LSB 0x04

#define OUT_Z_MSB 0x05
#define OUT_Z_LSB 0x06

void init_acc(void)
{
	CloseI2C2();   							//close i2c if was operating earlier
	
	TRISDbits.RD0 = 1;						//Configure SCL2 input
	ANSELDbits.ANSD0 = 0;					//RD0 digital port

	TRISDbits.RD1 = 1;						//Configure SDA2 input
	ANSELDbits.ANSD1 = 0;					//RD1 digital port
	
	OpenI2C2(MASTER, SLEW_ON);
	SSP2ADD = 0x0C; //~385kHz
	
	i2c_write( CTRL_REG1, 0x18);
	
	i2c_write( XYZ_DATA_CFG, 0x01);
	
	i2c_write( CTRL_REG4, 0x01);
	i2c_write( CTRL_REG5, 0x01);

	i2c_write( CTRL_REG1, 0x19);

}
Uint8 i2c_read(Uint8 reg_addr)
{
	Uint8 clearBuffer, reg_value;
	char status;

	IdleI2C2();								//check for bus idle condition in multi master communication

    //---START I2C COMMUNICATION---
    StartI2C2();

	//****write the address of the slave for communication***

    clearBuffer = SSP2BUF;					//read any previous stored content in buffer to clear buffer full status

	//R/W BIT IS '0' FOR FURTHER WRITE TO SLAVE
    do
    {
    status = WriteI2C2(DEVICE_ADRESS_ACCELERO_WRITE);	//write the address of slave
        if(status == -1)        			//check if bus collision happened
        {
            clearBuffer = SSP2BUF;     		//upon bus collision detection clear the buffer,
            SSP2CON1bits.WCOL=0;    		//clear the bus collision status bit
        }
    }
    while(status!=0);        				//write until successful communication	
	
	IdleI2C2();
	
	//****write the slave register address***
	while(WriteI2C2(reg_addr)!=0);
	
//---TERMINATE COMMUNICATION FROM MASTER SIDE---
	IdleI2C2();

//---RESTART I2C COMMUNICATION---
	RestartI2C2();
	IdleI2C2();

	//***write the address of the device for communication***
    clearBuffer = SSP2BUF;        			//read any previous stored content in buffer to clear buffer full status

	//R/W BIT IS '1' FOR READ FROM SLAVE
    do
    {
    status = WriteI2C2(DEVICE_ADRESS_ACCELERO_READ);
        if(status == -1)        			//check if bus collision happened
        {
            clearBuffer = SSP2BUF;       	//upon bus collision detection clear the buffer,
            SSP2CON1bits.WCOL=0;    		// clear the bus collision status bit
        }
    }
    while(status!=0);            			//write until successful communication	

	//****read the byte from slave register***
	reg_value = ReadI2C2();      			//recieve device ID from slave

    NotAckI2C2();         		           	//send the end of transmission signal through nack
    while( SSP2CON2bits.ACKEN!=0);    		//wait till ack sequence is complete
	
	IdleI2C2();
    
	StopI2C2();
	
	return reg_value;
}

void i2c_write(Uint8 reg_addr, Uint8 reg_value)
{
	Uint8 clearBuffer;
	char status;
	
	IdleI2C2();								//check for bus idle condition in multi master communication

    //---START I2C COMMUNICATION---
    StartI2C2();
	IdleI2C2();

	//****write the address of the slave for communication***

    clearBuffer = SSP2BUF;					//read any previous stored content in buffer to clear buffer full status
	
	//R/W BIT IS '0' FOR FURTHER WRITE TO SLAVE
	do
	{
	status = WriteI2C2(DEVICE_ADRESS_ACCELERO_WRITE);	//write the address of slave
       if(status == -1)        				//check if bus collision happened
       {
           clearBuffer = SSP2BUF;       	//upon bus collision detection clear the buffer,
           SSP2CON1bits.WCOL=0;    			//clear the bus collision status bit
       }
	}
	while(status!=0);        				//write untill successful communication

	IdleI2C2();
   
    //****write the slave register address***
	while(WriteI2C2(reg_addr)!=0);
   
	IdleI2C2();
   
	//***WRITE THE DATA TO BE SENT FOR SLAVE***
	while(WriteI2C2(reg_value)!=0);

	IdleI2C2();
	
	StopI2C2();
}

void ACC_get_xyz(signed int * x, signed int * y, signed int * z)
{
		signed int xbis, ybis, zbis;

		StartI2C2();
			*x = (unsigned int)(i2c_read(OUT_X_MSB)) << 6;
			IdleI2C2();
			RestartI2C2();
			*x |= (unsigned int)(i2c_read(OUT_X_LSB)) >> 2;
			IdleI2C2();
			RestartI2C2();
			*y = (unsigned int)(i2c_read(OUT_Y_MSB)) << 6;
			IdleI2C2();
			RestartI2C2();
			*y |= (unsigned int)(i2c_read(OUT_Y_LSB)) >> 2;
			IdleI2C2();
			RestartI2C2();
			*z = (unsigned int)(i2c_read(OUT_Z_MSB)) << 6;
			IdleI2C2();
			RestartI2C2();
			*z |= (unsigned int)(i2c_read(OUT_Z_LSB)) >> 2;
			IdleI2C2();
		StopI2C2();
	/*if(*x>8191)
		*x-=16384;
	if(*y>8191)
		*y-=16384;
	if(*z>8191)
		*z-=16384;*/
	xbis = *x;
	ybis = *y;
	zbis = *z;
//	printf("ACC %5d\t%5d\t%5d\t%5d\n",*x, *y, *z, *x+*y+*z);
}